package org.example.lotterysystem.service.activitystatus.impl;

import org.example.lotterysystem.common.errorcode.ServiceErrorCode;
import org.example.lotterysystem.common.exception.ServiceException;
import org.example.lotterysystem.service.ActivityService;
import org.example.lotterysystem.service.activitystatus.ActivityStatusManager;
import org.example.lotterysystem.service.activitystatus.operator.AbstractActivityOperator;
import org.example.lotterysystem.service.dto.ConvertActivityStatusDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Component
public class ActivityStatusManagerImpl implements ActivityStatusManager {
    private static final Logger log = LoggerFactory.getLogger(ActivityStatusManagerImpl.class);
    @Autowired
    private final Map<String, AbstractActivityOperator> operatorMap = new HashMap<>();
    @Autowired
    private ActivityService activityService;

    //处理活动相关状态转换
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        if(CollectionUtils.isEmpty(operatorMap)) {
            log.warn("operatorMap is empty");
            return;
        }
        Map<String, AbstractActivityOperator> curMap = new HashMap<>(operatorMap);
        Boolean update = false;
        //处理人员, 奖品
        update = processConvertStatus(convertActivityStatusDTO, curMap, 1);
        //处理活动
        update = processConvertStatus(convertActivityStatusDTO, curMap, 2) || update;
        //更新缓存
        if(update) {
            activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
        }
    }

    //回滚处理活动相关状态
    @Override
    public void rollbackhandlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        for (AbstractActivityOperator operator : operatorMap.values()) {
            operator.convert(convertActivityStatusDTO);
        }
        //缓存更新
        activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
    }

    //扭转状态
    private Boolean processConvertStatus(ConvertActivityStatusDTO convertActivityStatusDTO,
                                         Map<String, AbstractActivityOperator> curMap,
                                         int sequence) {
        Boolean update = false;
        //遍历curMap
        Iterator<Map.Entry<String, AbstractActivityOperator>> iterator = curMap.entrySet().iterator();
        while(iterator.hasNext()) {
            AbstractActivityOperator operator = iterator.next().getValue();
            //Operator是否需要转换
            if(operator.sequence()!=sequence || !operator.needConvert(convertActivityStatusDTO)) {
                continue;
            }
            //需要转换
            if (!operator.convert(convertActivityStatusDTO)) {
                log.error("{}状态转换失败", operator.getClass().getName());
                throw new ServiceException(ServiceErrorCode.ACTIVITY_STATUS_CONVERT_ERROR);
            }
            //curMap删除当前Operator
            iterator.remove();
            update = true;
        }
        //返回
        return update;
    }
}
